﻿//-----------------------------------------------------------------------
// <copyright file="NewWriteupsViewModel.cs" company="AFS">
// Copyright (c) AFS. All rights reserved.
//
//    This file is part of Chatbox.
//
//    Chatbox is free software: you can redistribute it and/or modify
//    it under the terms of the GNU Lesser General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    any later version.
//
//    Chatbox is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//    GNU Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public License
//    along with Chatbox. If not, see http://www.gnu.org/copyleft/lesser.html
// </copyright>
//----------------------------------------------------------------------- 

namespace ChatBox.UI.Windows.Tickers
{
    using System;
    using System.Collections.ObjectModel;
    using System.Windows;
    using System.Windows.Documents;

    using ChatBox.DomainObjects.ResultData;
    using ChatBox.DomainObjects.XmlFeedObjects;
    using ChatBox.UI.ViewModels;
    using ChatBox.XamlUtility;

    /// <summary>
    /// View model for new writeups display
    /// </summary>
    public class NewWriteupsViewModel : BaseViewModel
    {
        #region data

        /// <summary>
        /// New writeups
        /// </summary>
        private readonly ObservableCollection<NewWriteup> newWriteups = new ObservableCollection<NewWriteup>();

        /// <summary>
        /// Visiblity of the text for loading
        /// </summary>
        private Visibility loadingTextVisibility = Visibility.Visible;

        /// <summary>
        /// The document to display
        /// </summary>
        private FlowDocument document;

        #endregion

        #region public properties

        /// <summary>
        /// Gets or sets the visiblity of the text for loading
        /// </summary>
        public Visibility LoadingTextVisibility
        {
            get
            {
                return this.loadingTextVisibility;
            }

            set
            {
                if (this.loadingTextVisibility != value)
                {
                    this.loadingTextVisibility = value;
                    OnPropertyChanged("LoadingTextVisibility");
                }
            }
        }

        /// <summary>
        /// Gets or sets the FlowDocument to show
        /// </summary>
        public FlowDocument Document
        {
            get
            {
                return this.document;
            }

            set
            {
                if (this.document != value)
                {
                    this.document = value;
                    OnPropertyChanged("Document");
                }
            }
        }

        /// <summary>
        /// Gets the new writeups
        /// </summary>
        public ObservableCollection<NewWriteup> NewWriteups
        {
            get
            {
                return this.newWriteups;
            }
        }

        /// <summary>
        /// Gets or sets the hyperlink context
        /// </summary>
        public HyperlinkContext HyperlinkContext { get; set; }

        #endregion

        /// <summary>
        /// Process data received
        /// </summary>
        /// <param name="operationResult">the data to process</param>
        public void ProcessOperationResult(OperationResult operationResult)
        {
            NewWriteupsDataResult newWriteupsData = operationResult as NewWriteupsDataResult;
            if (newWriteupsData != null)
            {
                this.NewWriteups.Clear();
                this.NewWriteups.AddList(newWriteupsData.NewWriteups);

                this.GenerateDocument();
                this.LoadingTextVisibility = Visibility.Collapsed;
            }
        }

        /// <summary>
        /// Generate the document that is ciontent for this control
        /// </summary>
        private void GenerateDocument()
        {
            Paragraph content = new Paragraph();

            foreach (NewWriteup writeup in this.NewWriteups)
            {
                this.AddIntoParagraph(content, writeup);
                content.Inlines.Add(new LineBreak());
            }

            this.Document = new FlowDocument(content)
            {
                PagePadding = new Thickness(2)
            };
        }

        /// <summary>
        /// Add text for the new writeup into the paragraph
        /// </summary>
        /// <param name="content">the target paragraph</param>
        /// <param name="writeup">the writeup</param>
        private void AddIntoParagraph(Paragraph content, NewWriteup writeup)
        {
            Hyperlink writeupLink = new Hyperlink(new Run(writeup.Parent.Text));
            writeupLink.NavigateUri = this.NodeLink(writeup.Writeup.NodeId);
            content.Inlines.Add(writeupLink);

            content.Inlines.Add(" (" + writeup.WriteupType + ") by ");

            Hyperlink authorLink = new Hyperlink(new Run(writeup.Author.Text));
            authorLink.NavigateUri = this.NodeLink(writeup.Author.NodeId);
            content.Inlines.Add(authorLink);

            content.Inlines.Add(" (");
            Hyperlink allLink = new Hyperlink(new Run("all"));
            allLink.ToolTip = "Show all writeups in this node";
            allLink.NavigateUri = this.NodeLink(writeup.Parent.NodeId);
            content.Inlines.Add(allLink);
            content.Inlines.Add(")");

            if (this.HyperlinkContext != null)
            {
                this.HyperlinkContext.SetContextOnHyperlink(writeupLink);
                this.HyperlinkContext.SetContextOnHyperlink(authorLink);
                this.HyperlinkContext.SetContextOnHyperlink(allLink);
            }
        }

        /// <summary>
        /// Make a link to the given node
        /// </summary>
        /// <param name="nodeId">the node id to link to</param>
        /// <returns>the complete hyperlink</returns>
        private Uri NodeLink(int nodeId)
        {
            if (this.HyperlinkContext == null)
            {
                return null;
            }
            else
            {
                string result = this.HyperlinkContext.SitePrefix + "/node/" + nodeId;
                return new Uri(result);
            }
        }
    }
}
